package com.gxc.aspect;

import com.alibaba.fastjson.JSONObject;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

/**
 * Aop.
 *
 * @author 宫新程
 * @since 2019/2/14 9:58
 */
@Slf4j
@Aspect
@Component
public class MyAspect {

  /** 切入点表达式. */
  @Pointcut("execution(* com.gxc.controller.UserController.*(..))")
  public void loginPointCut() {}


  /** 环绕通知. */
  @Around("loginPointCut()")
  public Object loginAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {

    ServletRequestAttributes servletRequestAttributes =
        (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
    HttpServletRequest request = servletRequestAttributes.getRequest();
    StringBuffer requestURL = request.getRequestURL();
    log.info("Aop-请求Url：", requestURL);

    MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
    Method method = signature.getMethod();
    // 类名
    String className = proceedingJoinPoint.getTarget().getClass().getName();
    // 方法名
    String methodName = method.getName();
    // 参数名称
    String[] parameterNames = signature.getParameterNames();
    // 参数值
    Object[] args = proceedingJoinPoint.getArgs();

    Map<String, Object> paramMap = new HashMap<>();
    if (parameterNames != null && parameterNames.length > 0) {
      for (int i = 0; i < parameterNames.length; i++) {
        if (args[i] instanceof ServletRequest
            || args[i] instanceof HttpSession
            || args[i] instanceof ServletResponse) {
          continue;
        }
        paramMap.put(parameterNames[i], args[i]);
      }
    }
    log.info("类名：{}", className);
    log.info("方法名：{}", methodName);
    log.info("参数列表：{}", JSONObject.toJSONString(paramMap));

    Object obj = proceedingJoinPoint.proceed();

    log.info("切面执行完毕...");
    return obj;
  }
}
